//
// Created by Zsir on 2025/8/22.
//

#ifndef TCPCONNECTION_H
#define TCPCONNECTION_H

#include "Channel.h"
#include <string>
#include <memory>
#include <functional>
#include <netinet/in.h>

class EventLoop;
class Socket;

class TcpConnection : public std::enable_shared_from_this<TcpConnection> {
public:
    using Pointer = std::shared_ptr<TcpConnection>;
    using MessageCallback = std::function<void(const Pointer&, const std::string&)>;
    using CloseCallback = std::function<void(const Pointer&)>;

    TcpConnection(EventLoop* loop, int sockfd, const sockaddr_in& localAddr,
                  const sockaddr_in& peerAddr);
    ~TcpConnection();

    void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
    void setCloseCallback(const CloseCallback& cb) { closeCallback_ = cb; }

    void send(const std::string& message);
    void shutdown();

    EventLoop* getLoop() const { return loop_; }
    const std::string& name() const { return name_; }

    void connectEstablished();
    void connectDestroyed();

private:
    void handleRead();
    void handleWrite();
    void handleClose();
    void handleError();

    void sendInLoop(const std::string& message);
    void shutdownInLoop();

    EventLoop* loop_;
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    sockaddr_in localAddr_;
    sockaddr_in peerAddr_;
    std::string name_;

    MessageCallback messageCallback_;
    CloseCallback closeCallback_;

    std::string inputBuffer_;
    std::string outputBuffer_;
};

#endif // TCPCONNECTION_H